import 'package:dio/dio.dart';
import 'package:eh_mobile/common/store/index.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get_storage/get_storage.dart';
import 'package:logger/logger.dart';


// 请求拦截器
class NetCache extends Interceptor {
  // 持久化存储类
  final cache = GetStorage();
  final _logger = Logger();
  @override
  //发起请求
  void onRequest(
      RequestOptions options, RequestInterceptorHandler handler) async {
    if (options.extra["cache"] == true) {
      _logger.d('发起带缓存请求--${options.uri.toString()}\n请求参数--${options.data}--请求头部信息--${options.headers}');
    } else {
      _logger.d('发起请求--${options.uri.toString()}\n请求参数--${options.data}--请求头部信息--${options.headers}');
    }

    // refresh标记是否是"下拉刷新"
    bool refresh = options.extra["refresh"];

    //如果是下拉刷新，先删除相关缓存
    if (refresh) {
      if (options.extra['list'] == true) {
        //若是列表，则只要url中包含当前path的缓存全部删除（简单实现，并不精准）
        cache.remove(options.uri.toString());
      } else {
        // 如果不是列表，则只删除uri相同的缓存
        cache.remove(options.uri.toString());
      }
      return handler.next(options);
    }

    //如果请求需要缓存
    if (options.extra["cache"] == true &&
        (options.method.toLowerCase() == "get" ||
            options.method.toLowerCase() == "post")) {
      String key = options.extra["cacheKey"];
      if (key.isEmpty) {
        key = options.uri.toString();
      }

      var ob = cache.read(key);

      if (ob != null) {
        Response response = Response(
            data: ob,
            requestOptions: options.copyWith(extra: options.extra),
            statusCode: 200);
        _logger.d('返回缓存数据');
        return handler.resolve(response, true);
      }
    }
    handler.next(options);
  }

  @override
  // 请求返回
  onResponse(Response response, ResponseInterceptorHandler handler) async {
    RequestOptions options = response.requestOptions;

    if (options.extra["cache"] == true) {
      // 如果启用缓存，将返回结果保存到缓存
      _saveCache(response);
      _logger.d(
          '带缓存请求返回--${response.realUri}\n请求参数--${options.data}\n返回数据--${response.data}');
    } else {
      _logger.d(
          '请求返回--${response.realUri}\n请求参数--${options.data}\n返回数据--${response.data}');
    }

    handler.next(response);
  }

  @override
  // 请求错误
  void onError(DioError err, ErrorInterceptorHandler handler) {
    // Do something with response error
    ErrorEntity errorInfo = createErrorEntity(err);
    disposeError(errorInfo);
    return handler.next(err); //continue
    // 如果你想完成请求并返回一些自定义数据，可以resolve 一个`Response`,如`handler.resolve(response)`。
    // 这样请求将会被终止，上层then会被调用，then中返回的数据将是你的自定义response.
  }

  // 缓存数据
  void _saveCache(Response response) {
    RequestOptions options = response.requestOptions;
    if (options.extra["cache"] == true &&
        (options.method.toLowerCase() == "get" ||
            options.method.toLowerCase() == "post")) {
      String key = options.extra["cacheKey"];
      if (key.isEmpty) {
        key = options.uri.toString();
      }
      cache.write(key, response.data);
      _logger.d('缓存保存完成!');
    }
  }

  /*
   * error统一处理
   */
  // 错误处理
  void disposeError(ErrorEntity eInfo) {
    _logger.e('error.code -> ${eInfo.code}, error.message -> ${eInfo.message}');
    switch (eInfo.code) {
      case 401:
        // 退出登录
        UserStore().logout();
        EasyLoading.showError(eInfo.message);
        break;
      default:
        //EasyLoading.showError('未知错误');
        break;
    }
  }

  // 错误信息
  ErrorEntity createErrorEntity(DioError error) {
    switch (error.type) {
      case DioErrorType.cancel:
        return ErrorEntity(code: -1, message: "请求取消");
      case DioErrorType.connectionTimeout:
        return ErrorEntity(code: -1, message: "连接超时");
      case DioErrorType.sendTimeout:
        return ErrorEntity(code: -1, message: "请求超时");
      case DioErrorType.receiveTimeout:
        return ErrorEntity(code: -1, message: "响应超时");
      case DioErrorType.badResponse:
        {
          try {
            int errCode =
                error.response != null ? error.response!.statusCode! : -1;
            // String errMsg = error.response.statusMessage;
            // return ErrorEntity(code: errCode, message: errMsg);
            switch (errCode) {
              case 400:
                return ErrorEntity(code: errCode, message: "请求语法错误");
              case 401:
                return ErrorEntity(code: errCode, message: "没有权限");
              case 403:
                return ErrorEntity(code: errCode, message: "服务器拒绝执行");
              case 404:
                return ErrorEntity(code: errCode, message: "无法连接服务器");
              case 405:
                return ErrorEntity(code: errCode, message: "请求方法被禁止");
              case 500:
                return ErrorEntity(code: errCode, message: "服务器内部错误");
              case 502:
                return ErrorEntity(code: errCode, message: "无效的请求");
              case 503:
                return ErrorEntity(code: errCode, message: "服务器挂了");
              case 505:
                return ErrorEntity(code: errCode, message: "不支持HTTP协议请求");
              default:
                {
                  return ErrorEntity(
                    code: errCode,
                    message: error.response != null
                        ? error.response!.statusMessage!
                        : "",
                  );
                }
            }
          } on Exception catch (_) {
            return ErrorEntity(code: -1, message: "未知错误");
          }
        }
      default:
        {
          return ErrorEntity(code: -1, message: error.message.toString());
        }
    }
  }
}

// 异常处理
class ErrorEntity implements Exception {
  int code = -1;
  String message = "";
  ErrorEntity({required this.code, required this.message});

  @override
  String toString() {
    if (message == "") return "Exception";
    return "Exception: code $code, $message";
  }
}
